<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>SPA路由的简单实现</title>
</head>
<body>
  <div class="router_box">
    <a href="/home" class="router" replace="true">首页</a>
    <a href="/classify" class="router">分类</a>
    <a href="/car" class="router">购物车</a>
    <a href="/my" class="router">我的</a>
  </div>
  <div class="routerView">

  </div>
  <script>
    function Router(params){
      //容错处理
      this.mode = params.mode||"hash";
      this.routes = params.routes || [];
      this.init = function(){
        var that = this;
        //获取dom元素绑定事件
        document.querySelectorAll(".router").forEach(element=>{
          element.addEventListener("click",function(e){
            //取消默认事件
            e.preventDefault();
            //判断路由模式
            if(that.mode==="hash"){
              let index = window.location.href.indexOf("#");
              //判断替换与添加
              if (this.getAttribute('replace')){
                window.location.replace(window.location.href.slice(0, index)+'#'+this.getAttribute('href'));
              }else{
                window.location.hash = this.getAttribute('href');
              }
            }else{
              //history模式
              if(this.getAttribute('replace')){
                //http://localhost:9999/home
                window.history.replaceState({}, '', window.location.origin+this.getAttribute("href"));
              }else{
                //push模式
                window.history.pushState({}, '', window.location.origin+this.getAttribute("href"));
              }
            }
          })
        })
        // 监听路由改变,重定向也能监听
        if (that.mode == 'hash'){
            window.addEventListener('hashchange', function(){
                that.routeChange();
            })
        }else{
          window.addEventListener('popstate',function(){
            that.routeChange();
          })
        }
        // init之后执行routeChange
        this.routeChange();
      }
      this.routeChange=function(){
        if (this.mode === 'hash'){
            //页面渲染
            let newHash = window.location.hash;
            let index = this.routes.findIndex(item=>{
                return `#${item.path}` === newHash;
            })
            if (index !== -1){
                //渲染组件
                document.querySelector(".routerView").innerHTML = this.routes[index].component;
            }else{
                //先查找是否有重定向
                let redirectIndex = this.routes.findIndex(item=>{
                    return item.path === '*';
                })
                //有的话渲染
                if (redirectIndex !== -1){
                    let index = window.location.href.indexOf('#');
                    //挑战重定向页面
                    window.location.replace(window.location.href.slice(0, index)+'#'+this.routes[redirectIndex].redirect);
                }
            }
        }else {
          //history页面渲染
          let newHash = window.location.pathname;
          let index = this.routes.findIndex(item=>{
            return item.path===newHash
          })
          if(index!==-1){
             //渲染组件
             document.querySelector(".routerView").innerHTML = this.routes[index].component;
          }else{
            // 没找到重定向
            let defaultIndex = this.routes.findIndex(item=>{
              return item.path==="*";
            })
            //找到了重定向
            if(defaultIndex!==-1){
              window.history.replaceState({},"",window.location.origin+this.routes[defaultIndex].redirect);
              //重定向页面不会渲染,我们手动调一下
              this.routeChange();
            }
          }
        }
      }
      //初始化
      this.init();
    }
    new Router({
            mode: 'history',
            routes:[
                { path: '/home', component: '<h1>主页</h1><h4>新一代前端工程师：我们啥都会</h4>' },
                { path: '/classify', component: '<h1>新闻</h1><h4>今天2018-11-5，上课还得穿工装</h4>' },
                { path: '/car', component: '<h1>团队</h1><h4>WEB前端工程师</h4>' },
                { path: '/my', component: '<h1>关于</h1><h4>一面而高薪就业</h4>' },
                { path: '*', redirect:'/home'}
            ]
        });
  </script>
</body>
</html>